// 1.创建 Promise 构造函数
function Promise(callback){ //参数：执行器函数
    let self = this;

    // 2.2声明一个数组，用来保存成功和失败的回调
    this.arrs = []


    // 6.设置promise实例对象的默认状态
    this.PromiseState = 'pending'
    // 6.设置promise实例对象的默认结果值
    this.PromiseResult = undefined;

    // 4.声明 resolve 函数
    function resolve(value){
        // 3.1判断实例对象的状态是否修改过，如果修改过，没有必要执行了
        if(self.PromiseState !== 'pending') return;

        // 5.修改promise实例对象的状态
        self.PromiseState = 'fulfilled'
        // 5.修改peomise实例对象的结果值
        self.PromiseResult = value;

        // 2.4一旦执行成功的状态，我们就把保存的成功回调函数取出来执行
        // this.arrs = [{}]
        // item 是数组中的每一个元素  {}
        // 如果发现内部有保存的成功回调 => 将其立即放入任务队列中, 而不是立即执行
        if (self.arrs.length>0) {
          setTimeout(() => { // 使用宏任务来模拟的微任务
            self.arrs.forEach(item =>{
                item.abc(value)
            })
          }, 0)
        }
        
    
    }
    // 4.声明 reject 函数
    function reject(reason){
        // 3.1判断实例对象的状态是否修改过，如果修改过，没有必要执行了
        if(self.PromiseState !== 'pending') return;
        
        // 5.修改promise实例对象的状态
        self.PromiseState = 'rejected'
        // 5.修改peomise实例对象的结果值
        self.PromiseResult = reason;
        // 2.5一旦执行失败的状态，我们就把保存的失败回调函数取出来执行
        if (self.arrs.length>0) {
          setTimeout(() => { // 使用宏任务来模拟的微任务
            self.arrs.forEach(item =>{
                item.onRejected(value)
            })
          }, 0)
        }
    }
    // 3.调用执行器函数
    callback(resolve,reject);
}
// 2.添加then方法
Promise.prototype.then = function(onResolved,onRejected){
    const self = this
    // 6.2判断 onRejected 是不是函数
    // 如果不是，需要给他补一个腿 
    // 如果是，就不用管了
    if(typeof onRejected !== 'function'){
        // 需要设置一个默认值
        onRejected = reason => {
          throw reason;
        }
    }
    // 7.1值传递：判断 onResolved 是不是函数
    // 如果不是，需要给他补一个腿
    if(typeof onResolved !== 'function'){
        onResolved = value =>{
            return value;
        }
    }

    // 4.1 p.then()方法的返回值是新的promise实例对象
    return new Promise((resolve,reject)=>{

      /* 
      执行指定的成功/失败回调, 并根据执行结果更新返回promise的状态
      */
      function handle(callback) {
        try{
            let res = callback(self.PromiseResult)
            if(res instanceof Promise){
                res.then(resolve, reject)
            }else{
                resolve(res);
            }
        }catch(e){
            reject(e)
        }
      }

      // 7.根据修改后的状态，调用相关的函数
      if(this.PromiseState === 'fulfilled'){ // 成功
        // 能立即执行成功的回调吗?
        setTimeout(() => {
          handle(onResolved)
        })
      } else if(this.PromiseState === 'rejected'){ // 失败
        setTimeout(() => {
          handle(onRejected)
        })
      } else { // pending状态
          this.arrs.push({
              abc : function(value){
                handle(onResolved)
              },
              onRejected :function(reason){
                handle(onRejected)
              }
          })
      }
  
    })
    
};

// 6.1添加 catch方法
Promise.prototype.catch = function(onRejected){
    return this.then(undefined,onRejected)
}